/*******************************************************************************
  * 文件：StateMachine.h
  * 作者：djy
  * 版本：v1.0.0
  * 日期：2020.05.29
  * 说明：状态机
*******************************************************************************/
#ifndef _STATEMACHINE_H
#define _STATEMACHINE_H
    
/* 头文件 *********************************************************************/
#include "Typedefine.h"
#include "Constant.h"
#include "Macro.h"
#include "OS_Timer.h"

/* 宏定义 *********************************************************************/
// #define  STATE_MACHINE_DEBUG

#define  state_machine_state(state, next_state, wait, handler)   \
            {state, next_state, #state, wait, handler##0, handler##1}

/* 类型定义 *******************************************************************/
enum
{   
    STATE_CTRL_INIT  = 0,     //Op0 初始化当前状态
    STATE_CTRL_NEXT  = 1,     //切换为下一状态
    STATE_CTRL_WAIT  = 2,     //等待其他事件
    STATE_CTRL_RETRY = 3,     //重试当前状态
    STATE_CTRL_RUN   = 4,     //Op1 继续运行
};// 状态机函数执行之后的退出返回值

typedef enum
{
    eDEV_ONPOWER = 1,   //设备上电
    eDEV_STANDBY,       //待机模式
  	eDEV_LEFT_TIMING,   //左灶定时
  	eDEV_MID_TIMING,    //中灶定时
  	eDEV_RIGHT_TIMING,  //右灶定时
    eDEV_ERROR,     	//设备故障
    eDEV_DEMO,          //演示模式
}DevState_te;//设备状态

/* 变量声明 *******************************************************************/
typedef struct
{
    DevState_te State;     //当前状态
    DevState_te NextState; //下次状态
    const char *Name;      //状态名称
    U32 Wait;              //等待时间  单位ms
    U32 (*Op0)(U32 arg);   //状态机任务初次运行
    U32 (*Op1)(U32 arg);   //状态机任务继续运行
}StateMachineOps_ts;//状态机操作

typedef struct
{
    int LastState;         //上次状态
    int CurState;          //当前状态
    int TryCnt;            //重试次数
    U32 Init;              //初次运行标志位
    const StateMachineOps_ts *Op;//状态机操作指针
    Timer_ts sSMTimer;     //定时器
}StateMachine_ts;//状态机


/* 函数声明 *******************************************************************/
DevState_te StateMachine_GetLastState(void);
DevState_te StateMachine_GetCurState(void);
const char* StateMachine_GetCurStateName(void);
void StateMchine_ChangeLastState(void);
void StateMachine_Change(DevState_te state);
void StateMachine_Recover(DevState_te state);
void StateMchine_Init(void);
    
#endif

